package cn.yunyichina.provider.hymed.service.neusoft;

import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.hymed.constant.NeusoftConst;
import cn.yunyichina.provider.hymed.model.bo.NeusoftResponseBO;
import cn.yunyichina.provider.hymed.model.domain.HymedPaymentSettingDO;
import cn.yunyichina.provider.hymed.model.vo.BaseRequestVO;
import cn.yunyichina.provider.hymed.service.BaseService;
import cn.yunyichina.provider.hymed.util.RsaUtil;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.pay.PaymentSettingResponse;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.commons.RandomUtil;
import cn.yunyichina.utils.convert.XmlUtils;
import cn.yunyichina.utils.dozer.Dozer;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.Map;

public class NeusoftBaseService extends BaseService {

    private static final Logger logger = LoggerFactory.getLogger(NeusoftBaseService.class);

    public HymedPaymentSettingDO getNeusoftSessionId(BaseRequestVO requestVO) {
        HymedPaymentSettingDO responseDO = new HymedPaymentSettingDO();

        String appCode = requestVO.getAppCode();
        String orgCode = requestVO.getOrgCode();
        short payMode = Short.valueOf(NeusoftConst.HYMED_PAY_MODE);

        if (StringUtils.isBlank(appCode)) {
            throw new RuntimeException("NeusoftBaseService.getNeusoftSessionId->appCode前端入参不能为空!");
        }

        if (StringUtils.isBlank(orgCode)) {
            throw new RuntimeException("NeusoftBaseService.getNeusoftSessionId->orgCode前端入参不能为空!");
        }

        ResCommon<PaymentSettingResponse> resCommon = PayService.getPayClient().queryPaymentSettingByAppcodeAndOrgcodeAndPaymode(appCode, orgCode, payMode);
        if (!resCommon.isSuccess()) {
            throw new RuntimeException("NeusoftBaseService.getNeusoftSessionId->[appCode:" + appCode + "][orgCode:" + orgCode + "][payMode:" + payMode + "]找不到对应的河源医保支付的支付参数配置");
        }

        String sessionId = resCommon.getResult().getMerchantAccount() + StringUtils.rightPad(resCommon.getResult().getPartnerId(), 15, '0') + DateUtils.dateToString_yyMMddHHmmss(new Date()) + RandomUtil.getRandomNumberChar(3);
        responseDO.setSessionId(sessionId);
        responseDO.setPrivateKey(resCommon.getResult().getPrivateKey());
        responseDO.setPublicKey(resCommon.getResult().getPublicKey());
        responseDO.setMerchantId(resCommon.getResult().getSecretKey());
        return responseDO;
    }

    String getPrefixSoapHeader() {
        return "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:act=\"http://action.extinterfacenew.local.simis.si.neusoft.com\">\n" +
                "   <soapenv:Header/>\n" +
                "   <soapenv:Body>\n" +
                "      <act:YDYLService soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" +
                "         <Inxml xsi:type=\"soapenc:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" +
                "\t         <![CDATA[";
    }

    String getSuffixSoapHeader() {
        return "           ]]>\n" +
                "         </Inxml>\n" +
                "      </act:YDYLService>\n" +
                "   </soapenv:Body>\n" +
                "</soapenv:Envelope>";
    }

    <OUT extends NeusoftResponseBO> OUT getBusinessObject(String soapResponseContent, Class<OUT> out, String privateKey) {
        try {
            ObjectMapper xmlMapper = new XmlMapper();
            JsonNode node = xmlMapper.readTree(soapResponseContent.getBytes());

            ObjectMapper jsonMapper = new ObjectMapper();
            String json = jsonMapper.writeValueAsString(node);
            logger.info("NeusoftBaseService.getBusinessObject.json -> {}", json);

            Map map = JSON.parseObject(json, Map.class);
            Map body = (Map) map.get("Body");
            Map ydylServiceResponse = (Map) body.get("YDYLServiceResponse");
            Map ydylServiceReturn = (Map) ydylServiceResponse.get("YDYLServiceReturn");
            String resultXml = (String) ydylServiceReturn.get("");
            logger.info("NeusoftBaseService.getBusinessObject.resultXml.before.decrypt -> {}", resultXml);
            resultXml = RsaUtil.decryptByPrivateKey(resultXml, privateKey);
            logger.info("NeusoftBaseService.getBusinessObject.resultXml.after.decrypt -> {}", resultXml);
            Map<String, Object> resultMap = XmlUtils.xmlToUnifiedMap(resultXml);

            OUT response = Dozer.convert(resultMap, out);
            if (response.getErrorCode() != null && response.getErrorCode() > 0) {
                response.setBizSuccess(true);
            } else {
                response.setBizSuccess(false);
            }

            return response;
        } catch (Exception e) {
            logger.error("NeusoftBaseService.getBusinessObject.Exception", e);
            return null;
        }
    }

}
